import httpx
import asyncio
import datetime
import os
from typing import Optional
from dotenv import load_dotenv, find_dotenv

# 自动查找并加载 .env 文件
load_dotenv(find_dotenv())

class AuthManager:
    """
    管理内部系统的认证Token，包括获取、缓存和自动刷新。
    """
    def __init__(self, token_lifetime_minutes: int = 55):
        # 从环境变量读取认证信息
        self._base_url = os.getenv("INTERNAL_API_BASE_URL")
        self._credentials = {
            "password": os.getenv("INTERNAL_API_PASSWORD"),
            "verificationCode": "ahgd", # 根据您的脚本，此字段为固定值
            "name": os.getenv("INTERNAL_API_USERNAME"),
            "code": "ahgd", # 根据您的脚本，此字段为固定值
            "key": "11111" # 根据您的脚本，此字段为固定值
        }
        self._token_lifetime = datetime.timedelta(minutes=token_lifetime_minutes)
        self._token: Optional[str] = None
        self._token_expiry_time: Optional[datetime.datetime] = None
        self._lock = asyncio.Lock() # 异步锁，防止多个任务同时刷新token

        # 检查关键配置是否存在
        if not all([self._base_url, self._credentials["password"], self._credentials["name"]]):
            raise ValueError("[AuthManager] 关键环境变量 (INTERNAL_API_BASE_URL, INTERNAL_API_PASSWORD, INTERNAL_API_USERNAME) 未在 .env 文件中设置。")

    async def get_token(self) -> Optional[str]:
        """
        获取一个有效的Token。如果现有Token无效或将要过期，则自动刷新。
        """
        async with self._lock:
            if self._is_token_valid():
                print("[AuthManager] 使用缓存的有效Token。")
                return self._token

            print("[AuthManager] Token无效或已过期，正在获取新Token...")
            try:
                url = f"{self._base_url}/api/login"
                headers = {"Content-Type": "application/json"}
                
                async with httpx.AsyncClient(timeout=20.0) as client:
                    response = await client.post(url, json=self._credentials, headers=headers)
                    response.raise_for_status()
                    data = response.json()

                new_token = self._extract_token_from_response(data)

                if new_token:
                    print("[AuthManager] 成功获取新Token。")
                    self._token = new_token
                    self._token_expiry_time = datetime.datetime.now() + self._token_lifetime
                    return self._token
                else:
                    print("[AuthManager] [ERROR] 未能在API响应中找到Token。")
                    self._token = None
                    self._token_expiry_time = None
                    return None

            except httpx.HTTPStatusError as e:
                print(f"[AuthManager] [ERROR] 获取Token失败，状态码: {e.response.status_code}, 响应: {e.response.text}")
                return None
            except Exception as e:
                print(f"[AuthManager] [ERROR] 获取Token时发生未知错误: {e}")
                return None

    def _is_token_valid(self) -> bool:
        """检查当前Token是否存在且未过期。"""
        if self._token and self._token_expiry_time:
            return datetime.datetime.now() < self._token_expiry_time - datetime.timedelta(minutes=1)
        return False

    def _extract_token_from_response(self, data: dict) -> Optional[str]:
        """从API响应中智能提取Token。"""
        token_fields = ["token", "access_token", "auth_token", "jwt", "id_token"]
        for field in token_fields:
            if field in data:
                return data[field]
        for nested_key in ["result", "data"]:
            if nested_key in data and isinstance(data[nested_key], dict):
                for field in token_fields:
                    if field in data[nested_key]:
                        return data[nested_key][field]
        return None

async def main():
    print("--- 测试 AuthManager (从 .env 加载配置) ---")
    try:
        auth_manager = AuthManager()
        print("AuthManager 初始化成功。")
    except ValueError as e:
        print(f"[FAIL] AuthManager 初始化失败: {e}")
        print("请确保已在 .env 文件中正确设置 INTERNAL_API_BASE_URL, INTERNAL_API_USERNAME, 和 INTERNAL_API_PASSWORD。")
        return

    print("\n第一次尝试获取Token...")
    token1 = await auth_manager.get_token()
    if token1:
        print(f"成功获取Token 1: {token1[:15]}...")
    else:
        print("获取Token 1 失败。")

    print("\n第二次尝试获取Token (应使用缓存)...")
    token2 = await auth_manager.get_token()
    if token2:
        print(f"成功获取Token 2: {token2[:15]}...")
    else:
        print("获取Token 2 失败。")
        
    if token1 and token2:
        print(f"\nToken1 和 Token2 是否相同: {token1 == token2}")

if __name__ == "__main__":
    asyncio.run(main())
